package com.cquprt.Tcp;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import static com.cquprt.utils.TcpSocket.closeSAndC;
import static com.cquprt.utils.TcpSocket.writeData;
@Slf4j
@Data
public class TcpTransitMsgString {
    //外部改变此标志位，是否需要发送信息的标志，测试时默认为true
    public static volatile boolean needSendFlag=true;
    //停止本次Tcp连接
    public volatile static boolean stopThis=false;
    //停止掉Tcp连接,方便别人调用
    public static boolean stopTcp=false;
    //分割符号暂定为逗号
    private static final String spiltSign = ",";
    //固定的识别号
    private static final String identifyNum = 2+spiltSign;
    //车辆逆行
    private static String incident1=0+"";
    //闯红灯
    private static String incident2=0+"";
    //碰撞
    private static String incident3=0+spiltSign;
    //车牌号
    private static String carCode="渝AB0003"+spiltSign;
    //车行驶方向 0代表车头背对摄像头 1反之
    private static String toWard=1+"";
    /**
     * 功能：建立Tcp连接，发送数据
     * @param ip 需要连接的对象的ip
     * @param port 需要连接的对象的端口号
     */
    public static void transitMsg(String ip,int port){
        //接收数据的线程
        ReceiveThread receiveThread=new ReceiveThread();
        Socket client=null;
        InetAddress ia;
        BufferedOutputStream bo=null;
        BufferedInputStream bi=null;
        Thread.currentThread().setName(port+"写线程");
        try {
            ia=InetAddress.getByName(ip);
            log.info("客户端准备建立连接");
            //绑定端口和ip
            client=new Socket(ia,port);
            log.info("客户端建立连接成功！！！");
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //输出字节流
            bo=new BufferedOutputStream(client.getOutputStream());
            //输入字节流
            bi=new BufferedInputStream(client.getInputStream());
            //开线程接收数据
            startRecThread(port,receiveThread,bo,bi);
            //设定心跳时间60s
            client.setSoTimeout(60000);
            //写/读数据
            while (true){
                //stop为直接停止当前线程，另一个为读线程已经停止
                if (stopThis||receiveThread.isStopThread()){
                    break;
                }else {
                    //needSendFlag为true，表示有新的数据过来，需将上面的几个信息更新
                    //然后发送数据
                    if (needSendFlag){
                        sendMsg(port,bo);
                        needSendFlag=false;
                    }
                }
            }
        } catch (IOException e) {
            log.info(e.getMessage());
        }finally {
            //重置
            stopThis=false;
            //停止读线程
            receiveThread.setStopThread(true);
            //测试时报错就把它置为True
            needSendFlag=true;
            //关流，断开连接时不关client，因为已经断开
            if (!receiveThread.isStopThread()) {
                closeSAndC(null, null, bi, bo, null, client);
            }else {
                closeSAndC(bi, bo);
            }
            if (!stopTcp){
                //重启客户端 5s
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info(port+"写线程准备重连。。。");
                transitMsg(ip,port);
            }
        }
    }

    /**
     * 功能：将待输出的数据输出
     * @param bo 输出缓冲流
     */
    private static void sendMsg(int port,BufferedOutputStream bo){
        System.err.println(port+"本次发送的数据为："+identifyNum+incident1+incident2+incident3+carCode+toWard);
        writeData(identifyNum+incident1+incident2+incident3+carCode+toWard, bo);
    }

    /**
     * 功能：开启读线程，并将输入流和输出流传过去
     * @param receiveThread 读线程对象
     * @param bo 输出流
     * @param bi 输入流
     */
    private static void startRecThread(int port,ReceiveThread receiveThread,BufferedOutputStream bo,BufferedInputStream bi){
        receiveThread.setBi(bi);
        receiveThread.setBo(bo);
        receiveThread.setPort(port);
        receiveThread.setName(port+"读线程");
        receiveThread.start();
    }
}
